home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / macintosh technotes and q&as / technotes / tn / samplecode.sit.hqx / Sample Code / printing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-22  |  13.4 KB  |  490 lines

  1. /*
  2.     File:        printing.c
  3.  
  4.     Contains:    This file contains the printing routines for the QuickDraw GX shell
  5.                 application.
  6.  
  7.     Written by:    Developer Technical Support
  8.  
  9.     Copyright:    © 1992-1997 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Writers:
  12.  
  13.         (DMH)    Dave Hersey
  14.         (IK)    Ingrid Kelly
  15.  
  16.     Change History (most recent first):
  17.  
  18.          <9>      6/1/97    IK        Modified printing routines for GXGraphics 1.1.6.
  19.          <8>      8/1/94    DMH        Universalized.
  20.          <7>      5/1/94    DMH        More cleanup and debugging.
  21.          <6>      3/1/94    DMH        General cleanup and debugging.
  22.          <5>      3/1/94    DMH        Updated for b4.
  23.          <4>     12/1/93    DMH        Updated for b3.
  24.          <3>      9/1/93    PLA        Updated to run with the b2 "GXified" interface files.
  25.          <2>      2/1/93    DMH        Debugged and plopped on GX CD.
  26.          <1>      9/1/92    DMH        First created.
  27. */
  28.  
  29. #include <stdio.h>
  30. #include <Collections.h>
  31.  
  32. #include "CodecLibrary.h"
  33. #include "FontLibrary.h"
  34. #include "GraphicsLibraries.h"
  35.  
  36. #include "main.h"
  37.  
  38. /* ---------------------------------------------------------------------------
  39.     Function prototypes
  40.   --------------------------------------------------------------------------- */
  41.  
  42. static void        SetUpEditMenuRec(gxEditMenuRecord *menuRec);
  43. static void        FormatPageShape(gxprFormatHdl gxprFormat, gxShape shape);
  44.  
  45. /* ===========================================================================
  46.     Public functions
  47.   =========================================================================== */
  48.  
  49. /* ---------------------------------------------------------------------------
  50.     DoPageFormat
  51.     This routine performs GX's equivalent of the Page Setup (PrStlDialog) call
  52.     of the old printing architecture.
  53.   --------------------------------------------------------------------------- */
  54.  
  55. OSErr DoPageFormat(WindowPtr window, gxDialogResult *result)
  56. {
  57.     OSErr        error = noErr;
  58.  
  59.     *result = nil;
  60.  
  61.     /*    If we have a non-nil WindowPtr, set up our edit menu record and handle
  62.         the job format dialog. Remember to check for errors.
  63.     */
  64.     if ( window != nil )
  65.     {
  66.         TH_Document            document;
  67.         gxprJobHdl            gxprJob;
  68.         gxEditMenuRecord    edMenuRec;
  69.  
  70.         document = GetDocument(window);
  71.         gxprJob = GetDocumentJob(document);
  72.  
  73.         /*    Fill in the location of the application's Edit menu items. */
  74.  
  75.         SetUpEditMenuRec(&edMenuRec);
  76.  
  77.         *result = GXPrJobDefaultFormatDialog(gxprJob, &edMenuRec);
  78.         error = GXPrGetJobError(gxprJob);
  79.     }
  80.  
  81.     return error;
  82. }
  83.  
  84. /* ---------------------------------------------------------------------------
  85.     DoCustomPageFormat
  86.     This routine performs a by-page format. In other words, it sets formatting
  87.     info for only the current page.
  88.   --------------------------------------------------------------------------- */
  89.  
  90. OSErr DoCustomPageFormat(WindowPtr window, gxDialogResult *result)
  91. {
  92.     OSErr        error = noErr;
  93.  
  94.     /*    If we have a non-nil WindowPtr, set up our edit menu record and handle
  95.         the job format dialog. Remember to check for errors.
  96.     */
  97.     if ( window != nil )
  98.     {
  99.         TH_Document            document;
  100.         gxprJobHdl            gxprJob;
  101.         gxprFormatHdl        gxprFormat;
  102.         Boolean                isClonedFormat = false;
  103.         gxEditMenuRecord    edMenuRec;
  104.  
  105.         document = GetDocument(window);
  106.         gxprJob = GetDocumentJob(document);
  107.         gxprFormat = GetPageFormat(document, (*document)->page);
  108.  
  109.         /*    Use the default page format of the document print job. */
  110.  
  111.         if ( gxprFormat == nil )
  112.         {
  113.             gxprFormat = GXPrNewFormat(gxprJob);
  114.             error = GXPrGetJobError(gxprJob);
  115.  
  116.             if ( error != noErr )
  117.                 goto GXPrNewFormatFailed;
  118.  
  119.             isClonedFormat = true;
  120.         }
  121.  
  122.         /*    Fill in the location of the application's Edit menu items. */
  123.  
  124.         SetUpEditMenuRec(&edMenuRec);
  125.  
  126.         *result = GXPrFormatDialog(gxprFormat, &edMenuRec, nil);
  127.  
  128.         switch ( *result )
  129.         {
  130.             /*    If the user chooses Remove, store the default format for this page. */
  131.  
  132.             case gxRevertSelected:
  133.                 GXPrDisposeFormat(gxprFormat);
  134.                 SetPageFormat(document, (*document)->page, nil);
  135.                 break;
  136.  
  137.             case gxOKSelected:
  138.                 SetPageFormat(document, (*document)->page, gxprFormat);
  139.                 break;
  140.  
  141.             /*    If the user chooses Cancel, dispose of the cloned copy of the default format. */        
  142.  
  143.             case gxCancelSelected:
  144.                 if ( isClonedFormat )
  145.                     GXPrDisposeFormat(gxprFormat);
  146.                 break;
  147.         }
  148.  
  149.         error = GXPrGetJobError(gxprJob);
  150.     }
  151.  
  152. GXPrNewFormatFailed:
  153.     return error;
  154. }
  155.  
  156. /* ---------------------------------------------------------------------------
  157.     DoPrint
  158.     This routine performs GX's equivalent of the PrJobDialog call in the old
  159.     printing architecture, and then prints the document if the user wants to.
  160.   --------------------------------------------------------------------------- */
  161.  
  162. OSErr DoPrint(WindowPtr window)
  163. {
  164.     OSErr                error;
  165.  
  166.     /*    If we have a non-nil WindowPtr, set up our edit menu record and handle
  167.         the print job dialog. Remember to check for errors. If no errors occur,
  168.         and the user clicks ok, print the window's document.
  169.     */
  170.     if ( window != nil )
  171.     {
  172.         TH_Document            document;
  173.         gxprJobHdl            gxprJob;
  174.         gxEditMenuRecord    edMenuRec;
  175.         gxDialogResult        result;
  176.  
  177.         document = GetDocument(window);
  178.         gxprJob = GetDocumentJob(document);
  179.         
  180.         SetUpEditMenuRec(&edMenuRec);
  181.  
  182.         result = GXPrJobPrintDialog(gxprJob, &edMenuRec);
  183.         error = GXPrGetJobError(gxprJob);
  184.                 
  185.         if ( result == gxOKSelected && error == noErr )
  186.             error = DoPrintLoop(window);
  187.     }
  188.  
  189.     return error;
  190. }
  191.  
  192. /* ---------------------------------------------------------------------------
  193.     DoPrintOneCopy
  194.     This routine sets up our job collection items for printing one copy of a
  195.     document, and then prints the document.
  196.   --------------------------------------------------------------------------- */
  197.  
  198. OSErr DoPrintOneCopy(WindowPtr window)
  199. {
  200.     gxprJobHdl                gxprJob = nil;
  201.     gxCopiesInfo            *oldCopiesInfoPtr = nil;
  202.     gxFileDestinationInfo    *oldFileDestinationInfoPtr = nil;
  203.     gxPageRangeInfo            *oldPageRangeInfoPtr = nil;
  204.     long                    oldPageRangeInfoSize = 0;
  205.     OSErr                    error = noErr;
  206.  
  207.     /*    If we have a non-nil WindowPtr, start the print job, print a page and
  208.         then finish the job. Remember to check those errors!
  209.     */
  210.     if ( window != nil )
  211.     {
  212.         TH_Document                document;
  213.         gxCopiesInfo            copiesInfo;
  214.         gxFileDestinationInfo    fileDestinationInfo;
  215.         gxPageRangeInfo            pageRangeInfo;
  216.  
  217.         document = GetDocument(window);
  218.         gxprJob = GetDocumentJob(document);
  219.  
  220.         /*    Set the copies item to "one". */
  221.  
  222.         copiesInfo.copies = 1;
  223.         error = GXPrSetJobCopies(gxprJob, &copiesInfo, &oldCopiesInfoPtr);
  224.  
  225.         if ( error != noErr )
  226.             goto GXPrSetJobCopiesFailed;
  227.  
  228.         /*    Set the page range item to "all". */
  229.         
  230.         pageRangeInfo.simpleRange.optionChosen = gxDefaultPageRange;
  231.         pageRangeInfo.simpleRange.fromPage = 1;
  232.         pageRangeInfo.simpleRange.toPage = (*document)->pageCount;
  233.         pageRangeInfo.simpleRange.printAll = true;
  234.         pageRangeInfo.fromString[0] = '\0';
  235.         pageRangeInfo.toString[0] = '\0';
  236.         pageRangeInfo.minFromPage = 1;
  237.         pageRangeInfo.maxToPage = (*document)->pageCount;
  238.         pageRangeInfo.replaceString[0] = '\0';
  239.  
  240.         oldPageRangeInfoSize = sizeof(gxPageRangeInfo);
  241.  
  242.         error = GXPrSetJobPageRange(gxprJob, sizeof(gxPageRangeInfo), &pageRangeInfo, &oldPageRangeInfoSize, &oldPageRangeInfoPtr);
  243.  
  244.         if ( error != noErr )
  245.             goto GXPrSetJobPageRangeFailed;
  246.  
  247.         /*    Set the file destination item to "printer". */
  248.  
  249.         fileDestinationInfo.toFile = false;
  250.         error = GXPrSetJobFileDestination(gxprJob, &fileDestinationInfo, &oldFileDestinationInfoPtr);
  251.  
  252.         if ( error != noErr )
  253.             goto GXPrSetJobFileDestinationFailed;
  254.  
  255.         /*    Print one copy of the document. */
  256.  
  257.         error = DoPrintLoop(window);
  258.     }
  259.  
  260.     /*    Restore original number of copies, page range, and output destination. */
  261.  
  262. GXPrSetJobCopiesFailed:
  263.     if ( oldCopiesInfoPtr != nil )
  264.     {
  265.         (void) GXPrSetJobCopies(gxprJob, oldCopiesInfoPtr, nil);
  266.         DisposePtr((Ptr)oldCopiesInfoPtr);
  267.     }
  268.  
  269. GXPrSetJobPageRangeFailed:
  270.     if ( oldPageRangeInfoPtr != nil )
  271.     {
  272.         (void) GXPrSetJobPageRange(gxprJob, oldPageRangeInfoSize, oldPageRangeInfoPtr, 0, nil);
  273.         DisposePtr((Ptr)oldPageRangeInfoPtr);
  274.     }
  275.  
  276. GXPrSetJobFileDestinationFailed:
  277.     if ( oldFileDestinationInfoPtr != nil )
  278.     {
  279.         (void) GXPrSetJobFileDestination(gxprJob, oldFileDestinationInfoPtr, nil);
  280.         DisposePtr((Ptr)oldFileDestinationInfoPtr);
  281.     }
  282.  
  283.     return error;
  284. }
  285.  
  286. /* ---------------------------------------------------------------------------
  287.     DoPrintLoop
  288.     This routine prints the window's document using whatever job and format is
  289.     currently attached to it. (If the window wwere just created and then the
  290.     user selected Print One Copy w/o first selecting Page Setup…, the system
  291.     default job and format are stored with this document.
  292.   --------------------------------------------------------------------------- */
  293.  
  294. OSErr DoPrintLoop(WindowPtr window)
  295. {
  296.     OSErr    error = noErr;
  297.  
  298.     /*    If we have a non-nil WindowPtr, start the print job, print a page and
  299.         then finish the job. Remember to check those errors!
  300.     */
  301.     if ( window != nil )
  302.     {
  303.         TH_Document        document;
  304.         gxprJobHdl        gxprJob;
  305.         gxViewPort        viewport;
  306.         Str255            title;
  307.         gxprFormatHdl    gxprFormat;
  308.         gxShape         shape;
  309.         long            firstPage;
  310.         long            lastPage;
  311.         long            pg;
  312.         long            pageCount;
  313.  
  314.         document = GetDocument(window);
  315.         gxprJob = GetDocumentJob(document);
  316.         viewport = GetDocumentViewPort(document);
  317.  
  318.         GetWTitle(window, title);
  319.  
  320.         /*    Determine which pages the user selected to print. If the user specifies
  321.             a range that is greater than the actual number of pages, then only print
  322.             those pages that are in the document.
  323.         */
  324.         GXPrGetJobPageRange(gxprJob, &firstPage, &lastPage);
  325.  
  326.         pageCount = (*document)->pageCount;
  327.  
  328.         if ( firstPage < 1 )
  329.             firstPage = 1;
  330.         else if ( firstPage > pageCount )
  331.             firstPage = pageCount;
  332.  
  333.         if ( lastPage < firstPage )
  334.             lastPage = firstPage;
  335.         else if ( lastPage > pageCount )
  336.             lastPage = pageCount;
  337.  
  338.         /*    Calculate the total number of pages to print. */
  339.  
  340.         pageCount = lastPage - firstPage + 1;
  341.  
  342.         error = GXPrGetJobError(gxprJob);
  343.  
  344.         /*    Begin printing if there are no errors. */
  345.  
  346.         if ( error == noErr )
  347.         {
  348.             GXPrStartJob(gxprJob, title, pageCount);
  349.             error = GXPrGetJobError(gxprJob);
  350.             
  351.             for ( pg = firstPage; error == noErr && pg <= lastPage; pg++ )
  352.             {
  353.                 gxprFormat = GetPageFormat(document, pg);
  354.                 shape = GXCopyToShape(nil, GetPageShape(document, pg));
  355.  
  356.                 FormatPageShape(gxprFormat, shape);
  357.  
  358. #if 0
  359.                 /*    For each page, call the GXPrintPage function for the page's picture
  360.                     shape.
  361.                 */
  362.                 GXPrPrintPage(gxprJob, pg, gxprFormat, shape);
  363.                 error = GXPrGetJobError(gxprJob);
  364. #else
  365.                 /*    For each page, call the GXStartPage function, draw the page, and
  366.                     then call the GXFinishPage function. In this example, only a single
  367.                     shape is drawn for each page.
  368.                 */
  369.                 GXPrStartPage(gxprJob, pg, gxprFormat, 1, &viewport);
  370.                 error = GXPrGetJobError(gxprJob);
  371.  
  372.                 /*    Draw the data for the page if there are no errors. */
  373.  
  374.                 if ( error == noErr )
  375.                 {
  376.                     GXDrawShape(shape);
  377.                     error = (OSErr)GXGetGraphicsError(nil);
  378.                 }
  379.  
  380.                 if ( error == noErr )
  381.                     GXPrFinishPage(gxprJob);
  382. #endif
  383.  
  384.                 if ( shape != nil )
  385.                     GXDisposeShape(shape);
  386.             }
  387.  
  388.             /*    Finish printing. */
  389.  
  390.             GXPrFinishJob(gxprJob);
  391.  
  392.             if ( error == noErr )
  393.                 error = GXPrGetJobError(gxprJob);
  394.  
  395.         }
  396.     }
  397.  
  398.     return error;
  399. }
  400.  
  401. /* ===========================================================================
  402.     Private functions
  403.   =========================================================================== */
  404.  
  405. /* ---------------------------------------------------------------------------
  406.     SetUpEditMenuRec
  407.     This routine sets up an gxEditMenuRecord which references our edit menu.
  408.     This structure is used by the GXJobDefaultFormatDialog and
  409.     GXJobPrintDialog calls to allow cut, copy, and paste operations from the
  410.     dialogs.
  411.   --------------------------------------------------------------------------- */
  412.  
  413. static void SetUpEditMenuRec(gxEditMenuRecord *edMenuRec)
  414. {
  415.     edMenuRec->editMenuID = mEdit;
  416.     edMenuRec->cutItem = iCut;
  417.     edMenuRec->copyItem = iCopy;
  418.     edMenuRec->pasteItem = iPaste;
  419.     edMenuRec->clearItem = iClear;
  420.     edMenuRec->undoItem = iUndo;
  421. }
  422.  
  423. /* ---------------------------------------------------------------------------
  424.     FormatPageShape
  425.   --------------------------------------------------------------------------- */
  426.  
  427. static void FormatPageShape(gxprFormatHdl gxprFormat, gxShape shape)
  428. {
  429.     Collection                formatCollection;
  430.     T_CustomCollection        customConfig;
  431.     gxShape                 textShape;
  432.     Str255                    textStr;
  433.     long                    numChars;
  434.     OSErr                    error;
  435.  
  436.     if ( gxprFormat == nil )
  437.         return;
  438.  
  439.     if ( shape == nil )
  440.         return;
  441.  
  442.     formatCollection = GXPrGetFormatCollection(gxprFormat);
  443.     error = GXPrGetJobError(GXPrGetFormatJob(gxprFormat));
  444.  
  445.     if ( formatCollection == nil || error != noErr )
  446.         goto GXPrGetFormatCollectionFailed;
  447.  
  448.     error = GetCollectionItem(formatCollection, kCustomCollectionType, gxPrintingTagID, nil, &customConfig);
  449.  
  450.     if ( error != noErr )
  451.         goto GetCollectionItemFailed;
  452.  
  453.     if ( customConfig.one || customConfig.two || customConfig.three )
  454.     {
  455.         textShape = GXNewShape(gxTextType);
  456.         GXSetShapeTextSize(textShape, ff(32));
  457.         SetShapeCommonFont(textShape, timesFont);
  458.         GXMoveShapeTo(textShape, ff(10), ff(40));
  459.  
  460.         if ( customConfig.one )                            /* Enable page shuffling */
  461.         {
  462.             numChars = sprintf((Ptr)&textStr[0], "%s", "Enable page shuffling.");
  463.             GXSetText(textShape, numChars, textStr, nil);
  464.             AddToShape(shape, textShape);
  465.             GXMoveShape(textShape, ff(0), ff(40));
  466.         }
  467.  
  468.         if ( customConfig.two )                            /* Display page numbers */
  469.         {
  470.             numChars = sprintf((Ptr)&textStr[0], "%s", "Display page numbers.");
  471.             GXSetText(textShape, numChars, textStr, nil);
  472.             AddToShape(shape, textShape);
  473.             GXMoveShape(textShape, ff(0), ff(40));
  474.         }
  475.  
  476.         if ( customConfig.three != 0 )                    /* Flip image */
  477.         {
  478.             numChars = sprintf((Ptr)&textStr[0], "%s%d%s", "Flip image by ", customConfig.three, " degrees.");
  479.             GXSetText(textShape, numChars, textStr, nil);
  480.             AddToShape(shape, textShape);
  481.         }
  482.  
  483.         GXDisposeShape(textShape);
  484.     }
  485.  
  486. GetCollectionItemFailed:
  487. GXPrGetFormatCollectionFailed:
  488.     return;
  489. }
  490.